# koroFileHeader at Yungoal acer
# Create: 2023-03-31 15:50:43
# LastEdit: 2023-10-20 09:50:57
"""异步任务框架"""
__author__ = '749B'

import functools
import logging
import threading

from django.utils import timezone


class BaseTask(threading.Thread):
    """异步任务框架"""

    task_info_map = {}  # {(cls_name, task_name): {'begin': datetime.time, 'end': datetime.time}}
    logger = logging.getLogger("tasks.BaseTask")

    def __init__(self, task_name: str) -> None:
        super().__init__()
        self.task_key = (self.__class__.__name__, task_name)
        self.task_start_msg = None

    def start(self) -> bool:
        """任务start返回True, 未开始返回False"""
        task_info = self.__class__.task_info_map.get(self.task_key)
        task_not_fount = task_info is None
        # 无任务记录
        if task_not_fount:
            super().start()
            return True
        task_finished = task_info.get('end')
        # 任务已完成
        if task_finished:
            task_just_finished = (timezone.localtime() - task_finished).seconds < 180
            # 任务完成但是刚刚完成
            if task_just_finished:
                self.task_start_msg = f"任务执行频率过快，上次完成时间{task_finished:%H:%M:%S}"
                return False
            # 任务完成有一段时间了
            super().start()
            return True
        # 剩下的情况就是任务执行中
        task_begin = task_info.get('begin')
        task_last_seconds = (timezone.localtime() - task_begin).seconds
        self.task_start_msg = f"任务还在执行中，开始时间{task_begin:%H:%M:%S}，已运行{task_last_seconds}秒"
        return False

    @staticmethod
    def set_task_info(func):
        """装饰子类的run方法"""
        @functools.wraps(func)
        def wrapper(self, *arg, **kwargs):
            self.__class__.task_info_map[self.task_key] = {'begin': timezone.localtime()}
            res = func(self, *arg, **kwargs)
            self.__class__.task_info_map[self.task_key]['end'] = timezone.localtime()
            return res
        return wrapper

    @classmethod
    def get_task_status(cls, cls_name, task_name):
        """获取task的状态信息"""
        key = (cls_name, task_name)
        task_info = cls.task_info_map.get(key)
        if not task_info:
            return '无任务执行记录'
        begin = task_info.get('begin')
        end = task_info.get('end')
        if not end:
            return f'执行中 开始时间: {begin:%H:%M:%S} 已运行{(timezone.localtime() - begin).seconds}秒'
        return f'已完成 完成时间: {end:%H:%M:%S} 运行了{(end - begin).seconds}秒'
